package com.dpp.controller.user;

import com.dpp.config.WxInformation;
import com.dpp.context.BaseContext;
import com.dpp.dto.OrderDTO;
import com.dpp.entity.*;
import com.dpp.mapper.*;
import com.dpp.result.Result;
import com.dpp.service.OrderService;
import com.dpp.service.ProductInfoService;
import com.dpp.service.UserMoneyService;
import com.dpp.service.impl.WxPayService;
import com.dpp.vo.HistoryOrderVO;
import com.dpp.vo.WxPayRespVO;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


@RestController
@RequestMapping("/user/order")
@Slf4j
@CrossOrigin
public class OrderController {
    @Resource
    private WxInformation wxInformation;
    @Autowired
    private  InviteMapper inviteMapper;
    @Resource
    private WxPayService wxPayService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private UserMoneyService userMoneyService;
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private CouponBookMapper couponBookMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ActivityRecordMapper activityRecordMapper;

    /**
     * 提现申请
     * @return
     */
    @GetMapping("/withdraw")
    public Result withdraw(){
        log.info("提现申请");
        String openid = BaseContext.getCurrentId();
        return orderService.withdraw(openid);
    }

    /**
     * 发单
     * @param orderDTO
     * @return
     */
    @Transactional
    @PostMapping("/distribute")
    public Result submit(OrderDTO orderDTO) throws GeneralSecurityException, NotFoundException, IOException, URISyntaxException, HttpCodeException, ParseException {
        log.info("订单表:,{}", orderDTO);
        String openid = BaseContext.getCurrentId();
        //获取支付请求开关
        Boolean open = wxInformation.getOpen();
        //判断支付请求参数是否完整
        if(orderDTO.getProductId()==null||orderDTO.getIsUseDiscount()==null||orderDTO.getPhone()==null||orderDTO.getAmount()==null){
            return Result.error("请求数据出错");
        }
        if(orderDTO.getProductId()==1){
            if(orderDTO.getExpectTime()==null||orderDTO.getAddress()==null||orderDTO.getPackageInfo()==null&&orderDTO.getImages()==null){
                return Result.error("请求数据出错");
            }
        } else if (orderDTO.getProductId()==7) {
            if(orderDTO.getAddress()==null||orderDTO.getPackageInfo()==null&&orderDTO.getImages()==null){
                return Result.error("请求数据出错");
            }
        } else {
            if(orderDTO.getPackageInfo()==null||orderDTO.getRemark()==null){
                return Result.error("请求数据出错");
            }
        }
        ProductInfo productInfo = productInfoService.selectByID(orderDTO.getProductId());
        if(productInfo==null){
            return Result.error("请求商品数据不存在");
        }
        if(productInfo.getId().equals(11)){
            String pass = orderDTO.getPass();
            Invite invite= inviteMapper.selectByCode(pass);
            if(invite==null){
                return Result.error("查无此邀请码");
            }
            if(invite.getCount()<=0){
                return Result.error("邀请码次数用完了");
            }
            if(openid.equals(invite.getOpenid())){
                return Result.error("不可给自己使用");
            }
        }
        //进行商品金额校验
        String amount=wxPayService.CheckAmount(productInfo,orderDTO);
        String description="代跑跑";
        if(!amount.isEmpty()){
            if(open){
                orderDTO.setAmount(Double.parseDouble(amount)/100);
                String Out_trade_no = orderService.insert(orderDTO,Orders.NoPay);
                log.info("发起支付请求，商品描述：{}", description);
                log.info("发起支付请求，商品订单号：{}", Out_trade_no);
                WxPayRespVO wxPayRespVO = wxPayService.nativePay(description, amount, Out_trade_no);
                log.info("返回的实体参数： "+wxPayRespVO);
                return Result.success(wxPayRespVO);
            }else{
                orderDTO.setAmount(Double.parseDouble(amount)/100);
                String Out_trade_no = orderService.insert(orderDTO,Orders.TO_BE_CONFIRMED);
                Orders orders = orderMapper.selectByNumber(Long.valueOf(Out_trade_no));
                if(productInfo.getId().equals(1)){
                    if (amount.equals(productInfo.getNewUserPrice() + "")) {
                        LocalDateTime now = LocalDateTime.now();
                        ActivityRecord activityRecord1 = activityRecordMapper.selectByActivityId(openid, 1);
                        if(activityRecord1==null){
                            ActivityRecord activityRecord = ActivityRecord.builder().openId(openid).activityId(1).recordStartTime(now).RecordFinished(ActivityRecord.start).build();
                            activityRecordMapper.insert(activityRecord);
                        }
                    }
                }else if(productInfo.getId().equals(2)){
                    if(amount.equals(productInfo.getNewUserPrice()+"")){
                    LocalDateTime now = LocalDateTime.now();
                    ActivityRecord activityRecord=ActivityRecord.builder().openId(openid).activityId(3).recordStartTime(now).RecordFinished(ActivityRecord.start).build();
                    activityRecordMapper.insert(activityRecord);
                    }
                }
                if(orders.getIsUseCoupon()==1){
                    couponBookMapper.updateReduceCount(openid,orders.getCouponId());
                }
                //发单次数加1
                if(orders.getProductId()==1){
                    userMapper.updateTimes(openid);
                }
                Long OutTradeNo= Long.valueOf(Out_trade_no);
                orderMapper.updateStatus(OutTradeNo,1);
                return Result.success();
            }
        }
        return Result.error("支付金额错误");
    }

    /**
     * 历史订单
     * @return
     */
    @GetMapping("/getOrderList")
    public Result<HistoryOrderVO> historyOrders(){
        log.info("历史订单查询");
        HistoryOrderVO historyOrderVO = orderService.selectHisOrders();
        return Result.success(historyOrderVO);
    }
    @GetMapping("/getpath")
    public Result<HistoryOrderVO> getpath(String path){
        log.info("历史订单查询");
        HistoryOrderVO historyOrderVO = orderService.selectPathOrders(path);
        return Result.success(historyOrderVO);
    }

    /**
     * 取消当前订单
     *
     * @return
     */
    @Transactional
    @PutMapping("/cancel/{id}")
    public Result cancel(@PathVariable Integer id) throws GeneralSecurityException, NotFoundException, IOException, HttpCodeException {
        log.info("当前订单id:{}",id);
        Orders orders = orderService.selectOrderById(id);
        Set<Integer> set = new HashSet<>();
        // 向集合中添加元素
        set.add(1);
        set.add(-5);
        if(set.contains(orders.getOrderStatus())){
            String openid = orders.getOpenid();
            if(!openid.equals(BaseContext.getCurrentId())){
                return Result.error("大哥别乱搞");
            }
            String amount= String.valueOf((int)(orders.getAmount()*100));
            //订单id
            String Out_trade_no= String.valueOf(orders.getNumber());
            //退款id
            String out_refund_no= String.valueOf(orders.getNumber());

            String reason="代跑跑退款";
            log.info("发起退款请求,退款id：{}", out_refund_no	);
            //获取支付请求开关
            Boolean open = wxInformation.getOpen();
            if(open){
                Boolean refund = wxPayService.refund(Out_trade_no, out_refund_no, reason, amount);
                if(refund){
                    orderService.cancel(id, Orders.CANCELLED);
                    return Result.success("取消成功");
                }
            }else {
                orderService.cancel(id, Orders.CANCELLED);
                return Result.success("取消成功");
            }

        }
        return Result.error("取消失败");
    }

    /**
     * 已取件
     * @param id
     * @return
     */
    @Transactional
    @PutMapping("/take/{id}")
    public Result take(@PathVariable Integer id){
        log.info("当前订单id:{}",id);
        return orderService.take(id,Orders.RECEIVED);
    }

    /**
     * 已送达
     * @param id
     * @return
     */
    @Transactional
    @PutMapping("/arrive/{id}")
    public Result arrive(@PathVariable Integer id,@RequestBody MultipartFile image){
        log.info("当前订单id:{}",id);
        if(image!=null) {
            orderService.image(id, image);
        }
        return orderService.arrive(id,Orders.REACHED);
    }

    /**
     * 已确认
     * @param id
     * @return
     */
    @Transactional
    @PutMapping("/confirm/{id}")
    public Result confirm(@PathVariable Integer id){
        log.info("当前订单id:{}",id);
        Orders orders = orderService.selectOrderById(id);

        if(orders==null) {
            return Result.error("id错误");
        }

        String openid = orders.getOpenid();
        if(!openid.equals(BaseContext.getCurrentId())){
            return Result.error("大哥别乱搞");
        }
        if(orders.getOrderStatus()==4){
            orderService.confirm(id,Orders.COMPLETED);
            userMoneyService.save(orders);
            return Result.success("确认成功");
        }
        return Result.error("失败");
    }

    @Transactional
    @GetMapping("/download")
    public void download(String url,  HttpServletResponse response){
        orderService.download(url,response);
    }
    /**
     * 接单
     */

    /**
     * 接单
     * @param id
     * @return
     */
    @Transactional
    @PutMapping("/takeOrder/{id}")
    public Result<String> takeOrder(@PathVariable Integer id)
    {
        return orderService.takeOrder(id);
    }
    /**
     * 骑手取消接单
     * @param id
     * @return
     */
    @Transactional
    @PutMapping("/takeCancel/{id}")
    public Result<String> takeCancel(@PathVariable Integer id)
    {
        return orderService.takeCancel(id);
    }


}
